package org.supda.system.controller.websocket;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.supda.system.entity.TUser;
import org.supda.system.service.UserService;


/**
 * webScoket处理器类
 * 参考：
 * {@link} http://www.cnblogs.com/zhjh256
 * 
 * @author supda
 * @Date 2017-2-24 下午4:10:58
 *
 */
public class MyWSHandler implements WebSocketHandler {  
  
	//用于保存HttpSession与WebSocketSession的映射关系
	public static final Map<Long, WebSocketSession> userSocketSessionMap;

	static {
		userSocketSessionMap = new ConcurrentHashMap<Long, WebSocketSession>();
	}
	
	@Autowired private UserService userService;
	
	/**
	 * 建立连接后,把登录用户的id写入WebSocketSession,双工通讯 连接后 并且在这里心跳
	 */
    @Override  
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {  
/*        System.out.println("connect to the websocket success......");  
        session.sendMessage(new TextMessage("Server:connected OK!"));  */
    	
    	Long uid = (Long) session.getAttributes().get("uid");
	//	TUser user=userService.findById(uid);
		if (userSocketSessionMap.get(uid) == null) {
			userSocketSessionMap.put(uid, session);
		}

		
    	final Long id =0L;
    	
    	Random rd = new Random();
    	
    	//DecimalFormat df = new DecimalFormat("#.0000");
    	
    	//生成测试数据
		
			String data = "{\"data\":\"#\"}";
			while(session.isOpen()){
				session.sendMessage(new TextMessage(data.replace("#", rd.nextInt(100)+"")) );
				Thread.sleep(1000);
			}
    }  
  
	/**
	 * 消息处理，在客户端通过Websocket API发送的消息会经过这里，然后进行相应的处理,处理发送过来的消息
	 */
    @Override  
    public void handleMessage(WebSocketSession wss, WebSocketMessage<?> wsm) throws Exception {  
        /*TextMessage returnMessage = new TextMessage(wsm.getPayload()  
                + " received at server");  
        System.out.println(wss.getHandshakeHeaders().getFirst("Cookie"));  
        wss.sendMessage(returnMessage);  */
    	
    	if(wsm.getPayloadLength()==0)
			return;
    	
    	
    }  
  
	/**
	 * 消息传输错误处理
	 */
    @Override
    public void handleTransportError(WebSocketSession wss, Throwable thrwbl) throws Exception {  
        if(wss.isOpen()){  
            wss.close();  
        }  
        
        System.out.println("Websocket:" + wss.getId() + "已经关闭");
		Iterator<Entry<Long, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();
		// 移除当前用户的Socket会话
		while (it.hasNext()) {
			Entry<Long, WebSocketSession> entry = it.next();
			if (entry.getValue().getId().equals(wss.getId())) {
				userSocketSessionMap.remove(entry.getKey());
			}
		}	
       System.out.println("websocket connection closed......");  
    }  
  
	/**
	 * 关闭连接后
	 */
    @Override  
    public void afterConnectionClosed(WebSocketSession wss, CloseStatus cs) throws Exception {  
        System.out.println("websocket connection closed......");  
        
        System.out.println("Websocket:" + wss.getId() + "已经关闭");
		Iterator<Entry<Long, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();
		// 移除当前用户的Socket会话
		while (it.hasNext()) {
			Entry<Long, WebSocketSession> entry = it.next();
			if (entry.getValue().getId().equals(wss.getId())) {
				userSocketSessionMap.remove(entry.getKey());
			}
		}	
    }  
  
    /**
     * 握手成功 初始化操作在这里面进行
     *
     * @return
     */
    @Override  
    public boolean supportsPartialMessages() {  
    	
    	//一旦HTTP认证成功 这个方法先被调用 如果返回true 则进行上面那么N多方法的流程。如果返回的是false就直接拦截掉了。不会调用上面那些方法了！！
        //就好像个构造器一样。这个是处理器 BootstrapHandler的构造器~
    	
        return false;  
    }
    
    
    /**
	 * 给所有在线用户发送消息
	 * @param message
	 * @throws IOException
	 */
	public void broadcast(final TextMessage message) throws IOException {
		Iterator<Entry<Long, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();

		//多线程群发
		while (it.hasNext()) {

			final Entry<Long, WebSocketSession> entry = it.next();

			if (entry.getValue().isOpen()) {
				// entry.getValue().sendMessage(message);
				new Thread(new Runnable() {

					public void run() {
						try {
							if (entry.getValue().isOpen()) {
								entry.getValue().sendMessage(message);
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
					}

				}).start();
			}

		}
	}

	/**
	 * 给某个用户发送消息
	 * 
	 * @param userName
	 * @param message
	 * @throws IOException
	 */
	public void sendMessageToUser(Long uid, TextMessage message) throws IOException {
		WebSocketSession session = userSocketSessionMap.get(uid);
		if (session != null && session.isOpen()) {
			session.sendMessage(message);
		}
	}
}